#ifndef __SIM_SIMULATOR_H__
#define __SIM_SIMULATOR_H__

#include "nommgr.h"
#include <ode/ode.h>

#ifdef GCC295
#include <hash_map>
#else
#include <ext/hash_map>
#endif

#include "mmgr.h"

#include "Math.h"

class Collision;
class RigidBody;

struct RigidBodyHash : std::unary_function<RigidBody *, RigidBody *>
{
	size_t operator () (const RigidBody* rigidBody) const
	{
		return (size_t)rigidBody;
	}
};

class Simulator
{
	public:
		static Simulator* getInstance ();
	
	public:
		~Simulator ();

	public:
		void initialize ();
		void shutdown   ();
		
	public:
		dWorldID      getWorld        ();
		dJointGroupID getContactGroup ();

		void setTargetFps (Real targetFps);

	public:
		void beginFrame ();
		void frame      ();
		void endFrame   ();

		bool getIsCollisionHandled (RigidBody* rigidBody1, RigidBody* rigidBody2);
		
		void addCollision (RigidBody* rigidBody, Collision& collision);
		void addCollision (RigidBody* rigidBody1, RigidBody* rigidBody2, Collision& collision);
	
	protected:
		Simulator ();
		
	protected:
		bool isInitialized;
		bool isShutdown;

		dWorldID      world;
		dJointGroupID contactGroup;

		Real simStep;

#ifdef GCC295
		typedef std::hash_multimap<RigidBody*, RigidBody*, RigidBodyHash> CollisionSet;
#else
		typedef __gnu_cxx::hash_multimap<RigidBody*, RigidBody*, RigidBodyHash> CollisionSet;
#endif
		CollisionSet collisionSet;
};

#endif
